package com.mgq.juc.reentrantLock;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

import static java.lang.Thread.sleep;

/**
 * @author MaGuangQi
 * ReentrantLock的Condition
 * synchronized是条件不满足,都进入waitSet队列(只有一个休息室)等待
 * ReentrantLock 可以使用更细粒度的条件,比如没有等到外卖,就去外卖休息室等待.没有等到烟,就去等烟休息室等待
 * @date 2021-12-17 10:06
 **/
@Slf4j
public class TestCondition {

    private static ReentrantLock ROOM = new ReentrantLock();
    //等烟的
    private static Condition waitCigarette=ROOM.newCondition();
    //等外卖的
    private static Condition waitTakeout=ROOM.newCondition();

    private static boolean haveCigarette = false;
    private static boolean haveTakeOut = false;
    public static void main(String[] args) throws InterruptedException {

        new Thread(()->{
            ROOM.lock();
            try {
                log.debug("有烟没?{}",haveCigarette);
                while (!haveCigarette) {
                    waitCigarette.await();
                }
                log.debug("有烟了,开始干活了");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                ROOM.unlock();
            }

        },"小南").start();
        new Thread(()->{
            ROOM.lock();
            try {
                log.debug("有外卖没?{}",haveCigarette);
                while (!haveTakeOut) {
                    waitTakeout.await();
                }
                log.debug("有外卖了,开始干活了");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                ROOM.unlock();
            }
        },"小女").start();
        sleep(1000);
        new Thread(()->{
            ROOM.lock();
            try {
                //只有一个线程等待 signal()
                haveCigarette=true;
                waitCigarette.signal();
            }finally {
                ROOM.unlock();
            }
        },"送烟的").start();
        sleep(1000);
        new Thread(()->{
            ROOM.lock();
            try {
                //只有一个线程等待
                haveTakeOut=true;
                waitTakeout.signal();
            }finally {
                ROOM.unlock();
            }
        },"送外卖的").start();
    }
}
